<template>
  <el-row v-if="!needSplit || (needSplit && needSplitShowFlag)" class="metaPageTable">
    <el-row class="metaPageTable_row">
      <el-col
        :span="12"
        :style="tableSize && tableSize !== '' ? 'font-size:' + tableSize + 'px' : ''"
        >{{ tableTitle }}</el-col
      >
      <el-col :span="16" class="metaPageTable_col">
        <el-button
          v-for="(item, index) in btnGroup"
          :key="index"
          :disabled="item.type === 'disabled'"
          size="small"
          @click="btnOnClick(item)"
          >{{ item.title }}</el-button
        >
      </el-col>
    </el-row>
    <el-row class="metaPageTable_tableBg">
      <el-table
        ref="multipleTable"
        :cell-style="cellStyle"
        :data="myTableData.content"
        tooltip-effect="dark"
        style="width: 100%"
        :height="tableHeight == '' ? 'auto' : tableHeight"
        :row-key="rowKey"
        border
        :highlight-current-row="ifHighlight"
        @sort-change="sortChange"
        @selection-change="handleSelectionChange"
        @cell-click="cellClick"
      >
        <el-table-column
          v-if="needCheckbox"
          fixed
          type="selection"
          prop="table_selection"
          align="center"
          width="50"
        />
        <el-table-column
          v-if="needIndex"
          fixed
          type="index"
          prop="table_index"
          label="序号"
          align="center"
          width="50"
        />
        <el-table-column
          v-for="(tItem, tIndex) in displayItemVal"
          :key="tIndex"
          :formatter="formatter"
          align="center"
          :width="tItem.width ? tItem.width : ''"
          min-width="120"
          :label="tItem.label"
          :prop="tItem.prop"
          :sortable="tItem.sortable"
          :show-overflow-tooltip="
            !needSplit ? tIndex === displayItemVal.length - 1 : false
          "
        />
        <template v-if="needSplit">
          <el-table-column
            v-for="(tItem, tIndex) in splitKeys"
            :key="tItem.prop"
            :formatter="formatter"
            align="center"
            :width="tItem.width ? tItem.width : ''"
            min-width="120"
            :label="tItem.label"
            :prop="tItem.prop"
            :sortable="tItem.sortable"
            :show-overflow-tooltip="tIndex === splitKeys.length - 1"
          />
        </template>
        <el-table-column
          v-if="iconBtnGroup && iconBtnGroup.length > 0"
          :label="iconLabel"
          :width="iconBtnGroup.length === 1 ? 90 : 55 * iconBtnGroup.length"
          align="center"
        >
          <template slot-scope="scope">
            <el-tooltip
              v-for="(item, index) in iconBtnGroup"
              :key="index"
              :disabled="item.disabled"
              class="item"
              effect="dark"
              :content="item.content"
              placement="top"
            >
              <i
                :class="[item.class, 'iconBtn']"
                @click="iconBtnOnClick(scope.row, item)"
              />
            </el-tooltip>
          </template>
        </el-table-column>
        <el-table-column
          v-if="lineBtnGroup && lineBtnGroup.length > 0"
          fixed="right"
          label="操作"
          :width="
            lineBtnNum !== 0
              ? 68 * lineBtnNum
              : lineBtnGroup.length === 1
              ? 150
              : 68 * lineBtnGroup.length
          "
          align="center"
          prop="table_option"
        >
          <template slot-scope="scope">
            <template v-for="(item, index) in lineBtnGroup">
              <el-button
                v-if="!item.hideCheck || item.hideCheck(scope.row, item)"
                :key="index"
                type="text"
                size="mini"
                class="metaPageTable_lineBtn"
                @click="lineBtnOnClick(scope.row, item)"
              >
                {{ item.title }}
              </el-button>
            </template>
          </template>
        </el-table-column>
      </el-table>
    </el-row>
    <el-row style="text-align: center">
      <el-pagination
        :page-sizes="[10, 20, 30, 40, 50, 100]"
        layout="total, sizes, prev, pager, next, jumper"
        :current-page="page"
        :total="myTableData.totalElements"
        :page-size="limit"
        @size-change="handleSizeChange"
        @current-change="handleCurrentChange"
      />
    </el-row>
  </el-row>
</template>
<script>
import utils from "@/utils/utils";
import deepClone from "@/utils/deepClone";
// import { types } from 'util'
export default {
  name: "MetaPageTable",
  components: {},
  props: {
    isManualPaging: {
      type: Boolean,
      default: false,
    },
    isAutoReq: {
      // 控制table的类型。false -> 传入数据，true -> 传入访问地址和参数，组件自己获取数据
      type: Boolean,
      default: false,
    },
    needCheckbox: {
      // 是否显示checkbox
      type: Boolean,
      default: false,
    },
    needIndex: {
      // 是否显示序号
      type: Boolean,
      default: false,
    },
    ifHighlight: {
      // 是否高亮
      type: Boolean,
      default: false,
    },
    reqUrl: {
      // isAutoReq为true时传入的接口地址
      type: String,
      default: "",
    },
    reqMethod: {
      // get或post
      type: String,
      default: "",
    },
    reqData: {
      // 访问接口的参数
      type: Object,
      default: () => {
        return {};
      },
    },
    tableTitle: {
      // table标题
      type: String,
      default: "",
    },
    tableSize: {
      // table标题
      type: String,
      default: "",
    },
    tableData: {
      // isAutoReq为false时传入的数据
      type: Object,
      default: () => {
        return {};
      },
    },
    btnGroup: {
      type: Array,
      default: () => {
        return [];
      },
    },
    displayItem: {
      type: Array,
      default: () => {
        return [];
      },
    },
    hiddenItem: {
      // 隐藏列
      type: Array,
      default: () => {
        return [];
      },
    },
    lineBtnGroup: {
      type: Array,
      default: () => {
        return [];
      },
    },
    iconBtnGroup: {
      type: Array,
      default: () => {
        return [];
      },
    },
    iconLabel: {
      // table标题
      type: String,
      default: "",
    },
    rowWarnStyle: {
      /**
       * 2019/07/11 追加
       * fieldName：根据此字段的值设定行背景色及行字体颜色
       * fieldValue：当其值为此值时进行设定
       * backgroundColor：背景色
       * fontColor：字体颜色
       */
      type: Object,
      default: () => {
        return {
          fieldName: "",
          fieldValue: "",
          backgroundColor: "",
          fontColor: "",
        };
      },
    },
    rowKey: {
      // 行数据的Key
      type: String,
      default: "id",
    },
    needSplit: {
      type: Boolean,
      default: false,
    },
    splitDisplayItem: {
      type: Object,
      default: () => {
        return {
          label: "",
          prop: "",
          value: "",
          sign: "",
        };
      },
    },
    remarkKey: {
      type: String,
      default: "",
    },
    autoReqFirst: {
      type: Boolean,
      default: true,
    },
    tableHeight: {
      type: String,
      default: "550",
    },
    lineBtnNum: {
      type: Number,
      default: 0,
    },
  },
  data() {
    return {
      myTableData: {
        content: [],
        totalElements: 0,
      },
      multipleSelection: [],
      page: 1,
      limit: 10,
      displayItemVal: this.displayItem,
      displayItemCp: [],
      displayItemInTable: {},
      sortOption: {
        order: "",
        prop: "",
      },
      splitKeys: [],
      needSplitShowFlag: true,
    };
  },
  watch: {
    hiddenItem(newValue) {
      this.displayItemInTable = {};
      this.displayItemVal = deepClone(this.displayItemCp);
      if (newValue.length > 0) {
        let i = this.displayItemVal.length;
        while (i--) {
          for (const item in newValue) {
            if (this.displayItemVal[i].prop === newValue[item]) {
              this.displayItemVal.splice(i, 1);
            }
          }
        }
      }
      for (const i in this.displayItemVal) {
        this.displayItemInTable[this.displayItemVal[i].prop] = this.displayItemVal[i];
      }
    },
  },
  created() {
    if (this.autoReqFirst) {
      this.formDataInit();
    }
    this.displayItemInTable = {};
    this.displayItemCp = deepClone(this.displayItemVal);
    if (this.hiddenItem.length > 0) {
      let i = this.displayItemVal.length;
      while (i--) {
        for (const item in this.hiddenItem) {
          if (this.displayItemVal[i].prop === this.hiddenItem[item]) {
            this.displayItemVal.splice(i, 1);
          }
        }
      }
    }
    for (const i in this.displayItemVal) {
      this.displayItemInTable[this.displayItemVal[i].prop] = this.displayItemVal[i];
    }
  },
  methods: {
    // 单元格点击事件
    cellClick(row, column, cell, event) {
      this.$emit("cell-click", row, column, cell, event);
    },
    // 排序方法
    sortChange(event) {
      if (!this.isAutoReq) {
        this.$emit("sort-change", event);
      } else {
        this.formDataInit(false, {}, event);
      }
    },
    // 隐藏table内button
    buttonNeedHide(rowData, item) {
      let flag = true;
      if (!item.hideProp) return flag;
      if (Object.keys(item.hideProp).every((x) => rowData[x] === item.hideProp[x]))
        flag = false;
      return flag;
    },
    formDataInit(isRefresh, otherParams, sortData) {
      this.multipleSelection = [];
      /**
       * isRefresh可传入boolean类型，刷新数据
       * isRefresh可传入string类型，data - 刷新数据，title - 刷新标题，all - 全刷新
       */
      if (isRefresh) {
        if (typeof isRefresh === "string") {
          if (isRefresh === "all") {
            this.myTableData = {
              content: [],
              totalElements: 0,
            };
            this.page = 1;
            this.limit = 10;

            this.displayItemVal = [];
            this.displayItemVal = deepClone(this.displayItem);
          } else if (isRefresh === "data") {
            this.myTableData = {
              content: [],
              totalElements: 0,
            };
            this.page = 1;
            this.limit = 10;
          } else if (isRefresh === "title") {
            this.displayItemVal = [];
            this.displayItemVal = deepClone(this.displayItem);
          }
        } else if (typeof isRefresh === "boolean") {
          this.myTableData = {
            content: [],
            totalElements: 0,
          };
          this.page = 1;
          this.limit = 10;
        }
      } else {
        const pageInt = parseInt(this.myTableData.totalElements / this.limit);
        const pageFloat = this.myTableData.totalElements % this.limit > 0 ? 1 : 0;
        if (this.page > pageInt + pageFloat) {
          this.page = 1;
        }
      }
      if (this.isAutoReq) {
        const reqParams = {};
        reqParams.method = this.reqMethod;
        if (this.reqMethod === "post") {
          reqParams.url = this.reqUrl;
          reqParams.data = this.reqData;
          reqParams.data.page = this.page;
          reqParams.data.limit = this.limit;
          if (sortData && Object.keys(sortData).length > 0) {
            reqParams.data.sortOrderBy = sortData.prop;
            reqParams.data.sortType = sortData.order;
            this.sortOption.order = sortData.order;
            this.sortOption.prop = sortData.prop;
          } else {
            reqParams.data.sortOrderBy = this.sortOption.prop;
            reqParams.data.sortType = this.sortOption.order;
          }
        } else {
          reqParams.url = this.reqUrl + "?";
          for (const key in this.reqData) {
            reqParams.url += key + "=" + this.reqData[key] + "&";
          }
          reqParams.url += "page=" + this.page + "&limit=" + this.limit;
          if (sortData && Object.keys(sortData).length > 0) {
            reqParams.url +=
              "&sortOrderBy=" + sortData.prop + "&sortType=" + sortData.order;
            this.sortOption.order = sortData.order;
            this.sortOption.prop = sortData.prop;
          } else {
            reqParams.url +=
              "&sortOrderBy=" +
              this.sortOption.prop +
              "&sortType=" +
              this.sortOption.order;
          }
        }
        this.$fetch(reqParams).then((res) => {
          if (res.data.code === 200) {
            this.myTableData = {};
            let tData = {};
            tData = res.data.result;
            if (this.needSplit) {
              this.needSplitShowFlag = false;
              this.splitKeys = [];
              let idList = [];
              if (tData.content) {
                for (let i in tData.content) {
                  if (i == 0) {
                    let ids = tData.content[i][this.splitDisplayItem.prop];
                    idList = ids.split(this.splitDisplayItem.sign);
                    let labels = tData.content[i][this.splitDisplayItem.label];
                    let labelList = [];
                    labelList = labels.split(this.splitDisplayItem.sign);

                    for (let j in idList) {
                      let keysItem = {};
                      keysItem.label = labelList[j];
                      keysItem.prop = idList[j];
                      this.splitKeys.push(keysItem);
                    }
                  }
                  let values = tData.content[i][this.splitDisplayItem.value];
                  let valueList = values.split(this.splitDisplayItem.sign);
                  for (let j in valueList) {
                    tData.content[i][idList[j]] = valueList[j];
                  }
                }
              }
              this.$nextTick(() => {
                this.needSplitShowFlag = true;
              });
            }
            this.myTableData = deepClone(tData);
          } else {
            this.$notify.error({
              title: "错误",
              message: res.data.message,
            });
          }
        });
      } else {
        if (otherParams && Object.keys(otherParams).length > 0) {
          this.myTableData = {};
          this.myTableData.content = otherParams.content ? otherParams.content : [];
          this.myTableData.totalElements = otherParams.totalElements
            ? otherParams.totalElements
            : 0;
          this.page = otherParams.page ? otherParams.page : 1;
          this.limit = otherParams.limit ? otherParams.limit : 10;
        } else {
          for (const key in this.tableData) {
            if (key === "content") {
              this.myTableData.content = [];
              const listLength = this.tableData.content.length;
              const index = (this.page - 1) * this.limit;
              for (let i = index; i < listLength; i++) {
                if (i < index + this.limit) {
                  this.myTableData.content.push(this.tableData.content[i]);
                }
              }
            } else {
              this.myTableData[key] = this.tableData[key];
            }
          }
        }
      }
      // 重新布局table,修复fixed导致的列高度问题
      if (this.$refs.multipleTable) {
        this.$nextTick(() => {
          this.$refs.multipleTable.doLayout();
        });
      }
    },
    // 格式化时间
    formatter(row, column, cellValue, index) {
      if ( cellValue == "undefined" || cellValue == "null" || !this.displayItemInTable[column.property]){
        return cellValue;
      }
        
      const type = this.displayItemInTable[column.property].type;
      if (type === "time") {
        const format = this.displayItemInTable[column.property].format;
        return utils.parseTime(parseInt(cellValue), format);
      } else if (type === "if") {
        let value = "";
        if (this.displayItemInTable[column.property].format) {
          value = this.displayItemInTable[column.property].format[cellValue]
          if((!value || value == '') && this.displayItemInTable[column.property].format['else']) {
            value = this.displayItemInTable[column.property].format['else']
          }
        } else {
          value = "否";
          if (cellValue === "1") {
            value = "是";
          }
        }
        return value;
      } else if(type === 'json') {
        if(!cellValue) {
          return ''
        }
        let props = this.displayItemInTable[column.property].props
        let parseNum = this.displayItemInTable[column.property].parse ? this.displayItemInTable[column.property].parse : 1
        let datas = cellValue
        for(let i = 0; i < parseNum; i++) {
          datas = JSON.parse(datas)
        }
        let reStr = ''
        if(typeof datas === 'object') {
          for(let i in props) {
            let retain = props[i].retain && props[i].retain !== '' ? props[i].retain : 2
            if(i == 0) {
              reStr = props[i].label + ':' + (props[i].calculate ? (parseFloat(datas[props[i].key]) * props[i].calculate).toFixed(retain) : datas[props[i].key].toFixed(retain))
            }else {
              reStr += ' , ' + props[i].label + ':' + (props[i].calculate ? (parseFloat(datas[props[i].key]) * props[i].calculate).toFixed(retain) : datas[props[i].key].toFixed(retain))
            }
          }
        }
        return reStr
      } else if (type === "splicing") {
        let format = this.displayItemInTable[column.property].format;
        let datas = row
        let reStr = ''
        for(let i in format) {
          if(format[i].fType == 'string') {
            if(format[i].needSpace) {
              reStr += ' '+ format[i].key + ' '
            }else {
              reStr += format[i].key
            }
          }else if(format[i].fType == 'object') {
            if(format[i].needSpace) {
              reStr += ' '+ datas[format[i].key] + ' '
            }else {
              reStr += datas[format[i].key]
            }
          }
        }
        return reStr
      } else if (type === "enum") {
        // 2019/06/11 追加 枚举类型对应
        const enums = this.displayItemInTable[column.property].enums;
        for (const idx in enums) {
          const item = enums[idx];
          if (item.value === cellValue) {
            return item.text;
          }
        }
      } else if (type === "colorh") {
        return "";
      }
      return cellValue;
    },
    cellStyle({ row, column, rowIndex, columnIndex }) {
      const item = this.displayItemInTable[column.property];
      const ret = {};
      if (item) {
        const type = item.type;
        if (type === "colorh" || type === "colord") {
          return { background: row[column.property], color: "#fff" };
        }
        if (type === "levelColor" && row.levelColor) {
          return { background: row.levelColor, color: "#fff" };
        }
        if (type === "resultColor" && row.resultColor) {
          return { background: row.resultColor, color: "#fff" };
        }
        if (type === "proResultColor" && row.proResultColor) {
          return { background: row.proResultColor, color: "#fff" };
        }
        if (type === "if" && item.color) {
          ret.color = item.color[row[column.property]];
        }
      }
      // 2019/07/11 追加 行背景色设置对应
      if (column.property !== "table_option") {
        if (
          this.rowWarnStyle.fieldName !== "" &&
          row[this.rowWarnStyle.fieldName] === this.rowWarnStyle.fieldValue
        ) {
          if (this.rowWarnStyle.backgroundColor !== "") {
            ret.background = this.rowWarnStyle.backgroundColor;
          }
          if (this.rowWarnStyle.fontColor !== "") {
            ret.color = this.rowWarnStyle.fontColor;
          }
          return ret;
        }
      }
      return ret;
    },
    // 列表多选
    handleSelectionChange(val) {
      this.multipleSelection = val;
      this.btnGroup.forEach((item) => {
        if (item.type) {
          if (val.length === 0) {
            item.type = "able";
          } else if (val.length > 0) {
            item.type = "disabled";
          }
        }
      });
    },
    // 页码变化
    handleSizeChange(val) {
      this.limit = val;
      if (!this.isAutoReq && this.isManualPaging) {
        this.$emit("limitChange", val);
      } else {
        this.formDataInit();
      }
    },
    // 当前页面改变时会触发
    handleCurrentChange(val) {
      this.page = val;
      if (!this.isAutoReq && this.isManualPaging) {
        this.$emit("pageChange", val);
      } else {
        this.formDataInit();
      }
    },
    // 按钮点击事件
    btnOnClick(item) {
      const params = {};
      params.button = item.id;
      params.rows = this.multipleSelection;
      params.remarkKey = this.remarkKey;
      this.$emit("btnClick", params);
    },
    lineBtnOnClick(dataItem, btnItem) {
      const params = {};
      params.button = btnItem.id;
      params.rows = dataItem;
      params.remarkKey = this.remarkKey;
      this.$emit("lineBtnClick", params);
    },
    iconBtnOnClick(dataItem, btnItem) {
      const params = {};
      params.button = btnItem.id;
      params.rows = dataItem;
      this.$emit("iconBtnClick", params);
    },
    getMultipleSelection() {
      return this.multipleSelection;
    },
  },
};
</script>
<style lang="less">
.metaPageTable {
  // margin-bottom: 15px;
  padding: 15px;
  background: #fff;
  border: 1px solid #e4eaec;
  border-radius: 6px;
  overflow-y: hidden;
  box-sizing: border-box;
  .el-table th.gutter {
    display: table-cell !important;
  }
  .metaPageTable_tableBg {
    padding: 8px 0 15px;
    .metaPageTable_lineBtn > span {
      border-bottom: 1px solid #409eff;
      font-weight: bold;
    }
    .iconBtn:hover {
      color: #409eff;
    }
  }
  .metaPageTable_row {
    align-items: center;
    display: flex;
  }
  .metaPageTable_col {
    text-align: right;
  }
}
</style>
